// -----------------------------------------------------------------------
//  <copyright file="TokenParsingMiddleware.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2025 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://www.dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2025-02-14 16:02</last-date>
// -----------------------------------------------------------------------

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

using OpenIddict.Validation.AspNetCore;


namespace DaprPlus.Authorization.AspNetCore;

public class TokenParsingMiddleware(RequestDelegate next, ILogger<TokenParsingMiddleware> logger)
{
    /// <summary>
    /// 执行中间件拦截逻辑
    /// </summary>
    /// <param name="context">Http上下文</param>
    /// <param name="authService">MS权限服务</param>
    /// <returns></returns>
    public async Task InvokeAsync(HttpContext context, IAuthenticationService authService)
    {
        var token = context.Request.Headers.Authorization.ToString();
        if (!string.IsNullOrEmpty(token) && token.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
        {
            var result = await authService.AuthenticateAsync(context,
                OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
            if (result.Succeeded)
            {
                context.User = result.Principal;
            }
            else
            {
                var properties = result.Properties?.Items;
                var failure = result.Failure;

                if (properties != null && properties.Any())
                {
                    logger.LogWarning("Token Validation Failed: \n{Failure}\n{Properties}, ",
                    failure?.ToString(),
                    properties.ToTextJson());
                }
                else
                {
                    logger.LogWarning("Token验证失败 - Failure: {Failure}",
                        failure?.ToString() ?? "未提供详细信息");
                }
            }
        }

        await next(context);
    }
}
